#include <GL/glut.h>
#include <iostream>
#include "../draw.h"
#include "screens.h"
#include "externs.h"

#define INITEDITOR 0
#define MAPEDITOR 1
#define LEVELEDITOR 2

#define L -1
#define S 0
#define F 1
#define M 2
#define R 3
#define W 4
#define A 13
#define B 14
#define A1 15
#define B1 16
#define P 17
#define P1 18
#define P2 19
#define P3 20
#define H 21


//Dont Change Their Values
#define N1 5
#define N2 6
#define N3 7
#define N4 8
#define N11 9
#define N21 10
#define N31 11
#define N41 12



int toggleMapDetails=1;

int fromWhere=-1;


EditorScreen::EditorScreen()
{
	editorMode=INITEDITOR;
	instruction=-1;
}

void EditorScreen::setEnvironment(int mode,string filePath)
{
	if(mode==NEW)
	{
		editorMode=INITEDITOR;
		fromWhere=NEW;
	}
	else if(mode==EDIT)
	{
		fromWhere=EDIT;
		level.loadLevel("./maps/"+filePath);
		level.setFilePath(filePath);
		level.restoreLevel();
		editorMode=LEVELEDITOR;

		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		float mapX=level.getMap().getMapDimensionX();
		float mapY=level.getMap().getMapDimensionY();
		if(800.0/525.0>mapX/mapY)
		{
			level.left=(mapX-800.0*mapY/525.0)/2.0;
			level.right=(mapX+800.0*mapY/525.0)/2.0;
			level.bottom=-mapY/7.0;
			level.top=mapY;
			glOrtho(level.left,level.right,level.bottom,level.top,10,-10 );
		}
		else if(800.0/525.0<mapX/mapY)
		{
			level.left=0;
			level.right=mapX;
			level.bottom=mapY/2.0-27.0*mapX/64.0;
			level.top=525.0*mapX/1600.0+mapY/2.0;
			glOrtho(level.left,level.right,level.bottom,level.top,10,-10 );
		}
		else
		{
			level.left=0;
			level.right=mapX;
			level.bottom=-mapY/7;
			level.top=mapY;
			glOrtho(level.left,level.right,level.bottom,level.top,10,-10 );
		}
		glutPostRedisplay();
	}
}

void EditorScreen::display(void)
{
	glClearColor(0,0,0,0);
	glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

	// DISPLAY

	if(editorMode==INITEDITOR)
	{
		glColor3d(1,1,1);
		Draw::Text(225,275,"Please Initialize Map From Terminal",-1,BIGGER);
	}

	if(editorMode==MAPEDITOR)
	{
		if(toggleMapDetails)
			level.getMap().draw();
		else
			level.getMap().drawIslands();

		glColor3d(1,1,1);
		Draw::Text(level.left+16*(level.right-level.left)/20,level.bottom+(level.top-level.bottom)*5/80,"Press F to finalize",-1,SMALLER);
		Draw::Text(level.left+16*(level.right-level.left)/20,level.bottom+(level.top-level.bottom)*7/80,"Terrain Editor Mode",-1,SMALLER);
		if(instruction==S)
		{
			glColor3d(1,1,1);
			Draw::Text(level.left+(level.right-level.left)/20,level.bottom+(level.top-level.bottom)*4/80,"Please Enter Sea Level From Terminal [0-255]",-1,SMALL);
		}
	}

	if(editorMode==LEVELEDITOR)
	{
		glColor3d(1,1,1);
		Draw::Text(level.left+16*(level.right-level.left)/20,level.bottom+(level.top-level.bottom)*4/80,"Level Editor Mode",-1,SMALLER);
		if(toggleMapDetails)
			level.getMap().draw();
		else
			level.getMap().drawIslands();

		level.draw();

		if(instruction==M)
		{
			if(level.getMap().getSelectedIslands().size()!=0)
			{
				glColor3d(1,1,1);
				Draw::Text(level.left+(level.right-level.left)/20,level.bottom+(level.top-level.bottom)*4/80,"Please Enter Island Reward From Terminal",-1,SMALL);
			}
		}
		if(instruction==W)
		{
			glColor3d(1,1,1);
			Draw::Text(level.left+(level.right-level.left)/20,level.bottom+(level.top-level.bottom)*4/80,"Please Save File From Terminal",-1,SMALL);
		}
		if(instruction==N11 || instruction==N21 || instruction==N31 || instruction==N41)
		{
			glColor3d(1,1,1);
			Draw::Text(level.left+(level.right-level.left)/20,level.bottom+(level.top-level.bottom)*4/80,"Please Set Bonus From Terminal",-1,SMALL);
		}
	}


	glutSwapBuffers();


	// STANDART INPUT READ

	if(editorMode==INITEDITOR)
	{
		level.getMap().init();
		editorMode=MAPEDITOR;

		level.restoreLevel();

		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		float mapX=level.getMap().getMapDimensionX();
		float mapY=level.getMap().getMapDimensionY();
		if(800.0/525.0>mapX/mapY)
		{
			level.left=(mapX-800.0*mapY/525.0)/2.0;
			level.right=(mapX+800.0*mapY/525.0)/2.0;
			level.bottom=-mapY/7.0;
			level.top=mapY;
			glOrtho(level.left,level.right,level.bottom,level.top,10,-10 );
		}
		else if(800.0/525.0<mapX/mapY)
		{
			level.left=0;
			level.right=mapX;
			level.bottom=mapY/2.0-27.0*mapX/64.0;
			level.top=525.0*mapX/1600.0+mapY/2.0;
			glOrtho(level.left,level.right,level.bottom,level.top,10,-10 );
		}
		else
		{
			level.left=0;
			level.right=mapX;
			level.bottom=-mapY/7;
			level.top=mapY;
			glOrtho(level.left,level.right,level.bottom,level.top,10,-10 );
		}
		glutPostRedisplay();
	}

	if(editorMode==MAPEDITOR)
	{
		if(instruction==S)
		{
			level.getMap().setSeaLevel();
			instruction=-1;
			glutPostRedisplay();
		}
	}
	else if(editorMode==LEVELEDITOR)
	{
		if(instruction==M)
		{
			level.saveIsland();
			instruction=-1;
			glutPostRedisplay();
		}
		if(instruction==W)
		{
			if(fromWhere==NEW)
				level.saveFile(NEW);
			else if(fromWhere==EDIT)
				level.saveFile(EDIT);
			screenMode=OPENING;
			opening->init();
			level.resetLevel();
			instruction=-1;
			glutPostRedisplay();
		}
		if(instruction==N11 || instruction==N21 || instruction==N31 || instruction==N41)
		{
			level.setBonusPack();
			instruction=-1;
			glutPostRedisplay();
		}
	}
}

void EditorScreen::keyboard(unsigned char key,int x, int y)
{

	cout << (int)key << endl;
	if(key=='7' || key=='7')
	{
		toggleMapDetails=1;
		glutPostRedisplay();
		cout << instruction << endl;
	}
	if(key=='8' || key=='8')
	{
		toggleMapDetails=0;
		glutPostRedisplay();
		cout << instruction << endl;
	}
	if(editorMode==MAPEDITOR)
	{
		if(key=='l' || key=='L')
		{
			instruction=L;
			level.getMap().reloadHeightMap();
			glutPostRedisplay();
		}
		if(key=='s' || key=='S')
		{
			instruction=S;
			glutPostRedisplay();
		}
		if(key=='f' || key=='F')
		{
			instruction=-1;
			editorMode=LEVELEDITOR;
			glutPostRedisplay();
		}
	}
	else if(editorMode==LEVELEDITOR)
	{
		if(key=='0' || key=='0')
		{
			level.printIslands();
			glutPostRedisplay();
		}
		if(key=='9' || key=='9')
		{
			level.printRoutes();
			glutPostRedisplay();
		}

		if(instruction==-1 && (key=='m' || key=='M'))
		{
			instruction=M;
			glutPostRedisplay();
		}

		if(instruction==-1 && (key=='r' || key=='R'))
		{
			cerr << "Mode set to R" << endl;
			instruction=R;
			glutPostRedisplay();
		}

		if(instruction==-1 && (key=='a' || key=='A'))
		{
			cerr << "Mode set to A" << endl;
			instruction=A;
			glutPostRedisplay();
		}

		if(instruction==-1 && (key=='b' || key=='B'))
		{
			cerr << "Mode set to B" << endl;
			instruction=B;
			glutPostRedisplay();
		}

		if(instruction==-1 && (key=='p' || key=='P'))
		{
			cerr << "Mode set to P" << endl;
			level.deletePorts();
			instruction=P;
			glutPostRedisplay();
		}


		if(instruction==-1 && key=='1')
		{
			cerr << "Mode set to N1" << endl;
			instruction=N1;
			glutPostRedisplay();
		}

		if(instruction==-1 && key=='2')
		{
			cerr << "Mode set to N2" << endl;
			instruction=N2;
			glutPostRedisplay();
		}

		if(instruction==-1 && key=='3')
		{
			cerr << "Mode set to N1" << endl;
			instruction=N3;
			glutPostRedisplay();
		}

		if(instruction==-1 && key=='4')
		{
			cerr << "Mode set to N1" << endl;
			instruction=N4;
			glutPostRedisplay();
		}


		if(instruction==-1 && (key=='w' || key=='W'))
		{
			cerr << "Mode set to W" << endl;
			instruction=W;
			glutPostRedisplay();
		}

		if(instruction==-1 && (key=='q' || key=='Q'))
		{
			cerr << "Mode set to Q" << endl;
			level.resetLevel();
			screenMode=OPENING;
			opening->init();
			glutPostRedisplay();
		}

		if(instruction==-1 && (key=='h' || key=='H'))
		{
			cerr << "Mode set to H" << endl;
			instruction=H;
			if(level.highlightFirst())
				instruction=-1;
			glutPostRedisplay();
		}
		else if(instruction==H && (key=='h' || key=='H'))
		{
			cerr << "H continued" << endl;
			instruction=H;
			level.highlightNext();
			glutPostRedisplay();
		}
		else if(instruction==H && (key=='d' || key=='D' || key==127))
		{
			cerr << "Highlighted one will be deleted" << endl;
			instruction=H;
			if(level.deleteHighlighted())
				instruction=-1;

			glutPostRedisplay();
		}

		if((instruction==A1 || instruction==B1) && key==27)
		{
			level.deleteLastShip();
			instruction=-1;
			glutPostRedisplay();
		}
		else if((instruction==A|| instruction==B) && key==27)
		{
			instruction=-1;
			glutPostRedisplay();
		}
		else if((instruction==P || instruction==P1 || instruction==P2 || instruction==P3 ) && key==27)
		{
			level.deletePorts();
			instruction=-1;
			glutPostRedisplay();
		}
		else if(instruction==R && key==27)
		{
			level.deleteLastRoute();
			instruction=-1;
			glutPostRedisplay();
		}
		else if(instruction==H && key==27)
		{
			cerr << "Hightlight ended" << endl;
			level.endHighlight();
			instruction=-1;
			glutPostRedisplay();
		}
		else if(key==27)
		{
			cerr << "esc'ye bastin" << endl;
			level.getMap().resetSelectedIslands();
			glutPostRedisplay();
		}
	}
}

void EditorScreen::special(int key,int x, int y)
{}

void EditorScreen::specialUp(int key,int x, int y)
{}

void EditorScreen::keyboardUp(unsigned char key,int x, int y)
{}

void EditorScreen::mouse(int button, int state,int x, int y)
{
	if(editorMode==LEVELEDITOR)
	{
		if(instruction==R && state==GLUT_DOWN && button==GLUT_LEFT_BUTTON)
		{
			cout << "Mouse clicked at Mode R" << endl;
			if(level.addPointtoLastRoute(x,y))
				instruction=-1;
			glutPostRedisplay();
		}
		else if((instruction==N1 ||instruction==N2 ||instruction==N3 ||instruction==N4  )&& state==GLUT_DOWN && button==GLUT_LEFT_BUTTON)
		{
			cout << "Mouse clicked at Mode N1" << endl;
			if(level.addBonusPack(x,y,instruction-4))
				instruction+=4;
			glutPostRedisplay();
		}
		else if((instruction==A || instruction==B)&& state==GLUT_DOWN && button==GLUT_LEFT_BUTTON)
		{
			cout << "Mouse clicked at Mode A or B" << endl;
			if(instruction==A)
			{
				if(level.placeShip(1,x,y))
					instruction=A1;
			}
			else
			{
				if(level.placeShip(2,x,y))
					instruction=B1;
			}

			glutPostRedisplay();
		}
		else if((instruction==P)&& state==GLUT_DOWN && button==GLUT_LEFT_BUTTON)
		{
			cout << "Mouse clicked at Mode P" << endl;
			if(level.placePort(1,x,y))
				instruction=P1;

			glutPostRedisplay();
		}
		else if((instruction==P2)&& state==GLUT_DOWN && button==GLUT_LEFT_BUTTON)
		{
			cout << "Mouse clicked at Mode P1" << endl;
			if(level.placePort(2,x,y))
				instruction=P3;

			glutPostRedisplay();
		}
		else if(instruction==-1 && state==GLUT_DOWN && button==GLUT_LEFT_BUTTON)
		{
			level.selectIsland(x,y);
			glutPostRedisplay();
		}

		if((instruction==A1 || instruction==B1)&& state==GLUT_UP && button==GLUT_LEFT_BUTTON)
		{
			cout << "Mouse upped at Mode A or B" << endl;
			level.setLastShipsOrientation(x,y);
			instruction=-1;

			glutPostRedisplay();
		}

		else if((instruction==P1)&& state==GLUT_UP && button==GLUT_LEFT_BUTTON)
		{
			cout << "Mouse upped at Mode P1" << endl;
			level.setPortOrientation(1,x,y);
			level.setIslandOwner(1);
			instruction=P2;

			glutPostRedisplay();
		}
		else if((instruction==P3)&& state==GLUT_UP && button==GLUT_LEFT_BUTTON)
		{
			cout << "Mouse upped at Mode P1" << endl;
			level.setPortOrientation(2,x,y);
			level.setIslandOwner(2);
			instruction=-1;

			glutPostRedisplay();
		}
	}
}

void EditorScreen::motion(int x, int y)
{
	if(instruction==A1 || instruction==B1)
	{
		level.setLastShipsOrientation(x,y);
		glutPostRedisplay();
	}
	else if(instruction==P1)
	{
		level.setPortOrientation(1,x,y);
		glutPostRedisplay();
	}
	else if(instruction==P3)
	{
		level.setPortOrientation(2,x,y);
		glutPostRedisplay();
	}
}

void EditorScreen::passiveMotion(int x, int y)
{

	if(editorMode==LEVELEDITOR)
	{
		if(instruction==R)
		{
			level.updateLastRoutesLastMember(x,y);
			glutPostRedisplay();
		}
	}
}
